package com.app.baselibrary.delegate
import android.app.Activity
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.viewbinding.ViewBinding
import com.app.baselibrary.base.BaseActivity
import com.app.baselibrary.base.BaseFragment
import java.lang.reflect.ParameterizedType

/**
 * ui生命周期组件 代理接口 初始化当前组件：[bind]
 */

interface LifecycleComponent<VB: ViewBinding> {

    /**
     * 绑定activity页面所需组件
     * @param activity [AppCompatActivity]
     */
    fun bind(activity: AppCompatActivity)

    /**
     * 绑定fragment页面所需组件
     * @param fragment [Fragment]
     */
    fun bind(fragment: Fragment)


    /**
     * 获取[ViewBinding]
     */
    fun requireViewBinding(): VB

}

/**
 * 实现了组件代理类
 */
internal class ContextLifecycleComponent<VB: ViewBinding> : LifecycleComponent<VB>,
    DefaultLifecycleObserver{

    private var owner: Any? = null

    private var viewBinding: VB? = null

    override fun bind(activity: AppCompatActivity){
        this.owner = activity
        activity.lifecycle.addObserver(this)
        viewBinding = bindViewBinding(activity)
    }

    override fun bind(fragment: Fragment){
        this.owner = fragment
        fragment.lifecycle.addObserver(this)
        viewBinding = bindViewBinding(fragment)
    }




    private fun requireOwner(action:(LifecycleOwner)->Unit) {
        if (owner != null){
            if (owner is AppCompatActivity){
                action.invoke(owner as AppCompatActivity)
            }else if (owner is Fragment){
                action.invoke(owner as Fragment)
            }
        }
    }

    /**
     * 获取[ViewBinding]
     */
    override fun requireViewBinding(): VB {
        if (viewBinding == null){
            throw IllegalArgumentException("viewBinding can not init you should call bind method when ui create")
        }
        return viewBinding!!
    }

    /**
     * 获取Activity
     */
    private fun getActivity(): Activity? {
        if (owner == null || (owner !is Activity && owner !is Fragment)){
            return null
        }
        return if (owner is Activity){
            owner as Activity
        }else {
            (owner as Fragment).requireActivity()
        }
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        this.owner = null
    }


    /**
     * 绑定viewBinding
     * @param target activity 或者 fragment
     * @return ViewBinding
     */
    private fun <VB: ViewBinding>bindViewBinding(target: Any): VB{
        if (target !is BaseActivity<*> && target !is BaseFragment<*>){
            throw IllegalArgumentException("target 必须为 BaseActivity 或者 BaseFragment")
        }
        val layoutInflater = if (target is BaseFragment<*>) {
            target.layoutInflater
        }else {
            (target as BaseActivity<*>).layoutInflater
        }
        val targetClazz = target.javaClass
        val parameterizedType = targetClazz.genericSuperclass as ParameterizedType
        val viewBindingClazz = parameterizedType.actualTypeArguments[0] as Class<*>
        val method = viewBindingClazz.getDeclaredMethod("inflate", LayoutInflater::class.java)
        @Suppress("UNCHECKED_CAST")
        return method.invoke(null, layoutInflater) as VB
    }

//    /**
//     * 绑定viewModel
//     * @param target activity 或者 fragment
//     * @return ViewBinding
//     */
//    private fun <VM: BaseViewModel>bindViewModel(target: Any): VM {
//        if (target !is BaseActivity<*, *> && target !is BaseFragment<*, *>){
//            throw IllegalArgumentException("target 必须为 BaseActivity 或者 BaseFragment")
//        }
//
//        val targetClazz = target.javaClass
//        val parameterizedType = targetClazz.genericSuperclass as ParameterizedType
//        val viewModelClazz = parameterizedType.actualTypeArguments[1] as Class<*>
//        @Suppress("UNCHECKED_CAST")
//        return if (target is BaseFragment<*, *>) {
//            ViewModelProvider(target).get(viewModelClazz as Class<VM>)
//        }else {
//            ViewModelProvider(target as BaseActivity<*, *>)[viewModelClazz as Class<VM>]
//        }
//    }

}

/**
 * [LifecycleComponent] 代理方法
 * 当前方法用在[AppCompatActivity] [Fragment]
 * eg: class MainActivity : AppCompatActivity(),LifecycleComponent<VB> by lifecycleComponent() {
 *          override fun onCreate(savedInstanceState: Bundle?) {
 *                super.onCreate(savedInstanceState)
 *                bind(this)
 *                setContentView(requireViewBinding().root)
 *         }
 *    }
 * eg: class MainFragment : Fragment(),LifecycleComponent<VB> by lifecycleComponent() {
 *          override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
 *               bind(this)
 *               return requireViewBinding().root
 *        }
 *   }
 */
internal fun <VB: ViewBinding>lifecycleComponent()=
    ContextLifecycleComponent<VB>()